package com.hitqz.robot.driver.zmq.protocol.handler;

import com.example.tutorial.AddressBookProtos;
import com.google.common.util.concurrent.RateLimiter;
import com.hitqz.robot.driver.dto.PowerInfoDto;
import com.hitqz.robot.driver.util.WheelCacheUtil;
import com.hitqz.robot.driver.util.WheelToolkit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;

/**
 * Int32Array数据类型处理类
 *
 * @author wengyx
 * @date 2021-09-13 17:15
 **/
@Slf4j
@Component
public class Int32ArrayHandler implements HandlerZMQService {

    private static final RateLimiter logLimiter = RateLimiter.create(1);

    @Override
    public void handlerMsg(String robotSn, byte[] data) throws Exception {
        AddressBookProtos.Int32Array int32Array = AddressBookProtos.Int32Array.parseFrom(data);
        String type = int32Array.getDescriptorForType().getName();
        int ackId = int32Array.getHeader().getAck();
        int objId = int32Array.getHeader().getObj();
        switch (objId) {
            // 各类传感器的配备数量
            case AddressBookProtos.Int32Array.OBJ_ID.GET_SENSOR_COUNT_REP_VALUE -> {
                HashMap<String, Integer> sensorCountMap = getStringIntegerHashMap(int32Array);
                WheelCacheUtil.put(WheelCacheUtil.KEY_SENSOR_COUNT, sensorCountMap);
            }
            // 电量信息
            case AddressBookProtos.Int32Array.OBJ_ID.GET_POWER_INFO_REP_VALUE,
                 AddressBookProtos.Int32Array.OBJ_ID.NUL_POWER_INFO_NTF_VALUE -> {
                int info = int32Array.getDataCount();
                PowerInfoDto powerInfo = new PowerInfoDto();
                powerInfo.setPower(info == 0 ? 0 : (float) (int32Array.getData(0)));
                powerInfo.setVoltage(info == 0 ? 0 : (float) (int32Array.getData(1) * 0.1));
                powerInfo.setCurrent(info == 0 ? 0 : (float) (int32Array.getData(2) * 0.1));
                powerInfo.setCapacitance(info == 0 ? 0 : (float) ((Integer) int32Array.getData(3)).doubleValue());
                powerInfo.setTemplate(info == 0 ? 0 : (float) ((Integer) int32Array.getData(4)).doubleValue());
                powerInfo.setCurrentDirection(info == 0 ? 0 : (int) ((Integer) int32Array.getData(5)).doubleValue());
                //充电状态在不同消息处理类里
                Integer chargeStatus = (Integer) WheelCacheUtil.get(WheelCacheUtil.KEY_RECHARGE_STATUS);
                if (chargeStatus != null) {
                    powerInfo.setChargeStatus(chargeStatus);
                }
                WheelCacheUtil.put(WheelCacheUtil.KEY_POWER_INFO, powerInfo);
                if (logLimiter.tryAcquire(10)){
                    log.info("[wheel]power :{}",powerInfo);
                }
                //todo 发布电量事件->低电量自主充电
            }
            // 声呐避障距离和释放距离

            // 声呐当前数据

            // 底盘设备告警信息 详情见协议
        }

        //释放锁
        WheelToolkit.release(ackId,type, objId, true);
    }

    private static HashMap<String, Integer> getStringIntegerHashMap(AddressBookProtos.Int32Array int32Array) {
        HashMap<String, Integer> sensorCountMap = new HashMap<>();
        sensorCountMap.put("imu", int32Array.getData(0));
        sensorCountMap.put("sonar", int32Array.getData(1));
        sensorCountMap.put("dropProof", int32Array.getData(2));
        sensorCountMap.put("antiCollision", int32Array.getData(3));
        //红外雷达
        sensorCountMap.put("infrared", int32Array.getData(4));
        //安全雷达
        sensorCountMap.put("lidar", int32Array.getData(5));
        //毫米波雷达
        sensorCountMap.put("wave", int32Array.getData(6));
        sensorCountMap.put("pgv", int32Array.getData(7));
        sensorCountMap.put("magnet", int32Array.getData(8));
        sensorCountMap.put("uwb", int32Array.getData(9));
        return sensorCountMap;
    }

    /**
     * int转32位bit的 byte数组  byte[0]为低位
     */
    private byte[] int2BooleanArray(int data) {
        byte[] bytes = new byte[4];
        bytes[3] = (byte) (data >> 24);
        bytes[2] = (byte) (data >> 16);
        bytes[1] = (byte) (data >> 8);
        bytes[0] = (byte) data;
        byte[] array = new byte[32];
        for (int j = 0; j < 4; j++) {
            byte b = bytes[j];
            for (int i = 8 * j; i < 8 * (j + 1); i++) {
                array[i] = (byte) (b & 1);
                b = (byte) (b >> 1);
            }
        }
        return array;
    }


}
